package com.haisen.poi.basic_poi;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.*;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.converters.BigDecimalConverter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.xml.sax.SAXException;


@Slf4j
public class BigExcelUtil extends BigExcelReader{

	//excel标题和序号,mode类的excel属性，order对应要导入excel表格的列
	  List<ExcelHeader> excelHeaders = new ArrayList<>();
	  // 类的属性和对应excel文档的列序号，用
	  Map<Integer, String> headMap = new HashMap<>();
	  Class clz = null;
	  //读取excel2obj
	  List<Object> objs = new ArrayList<>();
	
		private static BigExcelUtil bExcelUtil= new BigExcelUtil();
		private  BigExcelUtil() {
		}
		
		public static BigExcelUtil getInstance(){
			//注册字符串，数字（1900-1-1的天数）到日期转换器
			ConvertUtils.register(new SQLDateConverter(),Date.class);
			//注册bigdecimalConvert转换器
			BigDecimalConverter bd = new BigDecimalConverter(BigDecimal.ZERO);
			ConvertUtils.register(bd, BigDecimal.class);
			return bExcelUtil ;
		}

	public List<Object> importExcel2Obj(String pathfile,Class clz){
		this.clz = clz;
		 objs.clear();
	   	//获取类的excel注解属性
		    excelHeaders = getHeaderList(clz);
		  try {
			  // 读取excel文档
			 excelReaderByPath(pathfile);
		} catch (IOException | OpenXML4JException | SAXException e) {
			e.printStackTrace();
		}
		  //解析文档
		  parse();
		return objs;
	}
		
	@Override
	protected void outputRow(String[] datas, String[] rowTypes, int rowIndex) {
		    //读取excel标题
				if(rowIndex == 0 ){
					    //类的excel属性注解和excel标题关联，根据title
					//todo:第一行区字段名称，第二行去字段类型，来建立数据库脚本
					  headMap = getHeaderMap(datas);
					  for (Map.Entry<Integer, String> headm : headMap.entrySet()){
						  System.out.println("读取EXCEL第："+headm.getKey()+" 列，"+datas[headm.getKey()]+"|对应类属性："+headm.getValue());
					  }

				 }
				 else {
					 //处理一行的的列
					Object obj = null;
					 try {
							obj =this.clz.newInstance();
						} catch (InstantiationException e1) {
							e1.printStackTrace();
						} catch (IllegalAccessException e1) {
							e1.printStackTrace();
						}	
					 for(int colIndex = 0; colIndex < datas.length; colIndex ++){
			        			  try {
			        				   if (headMap.keySet().contains(colIndex)){
			        					    String content = datas[colIndex]==null ? "" : datas[colIndex];
			        					   // log.info("属性拷贝：属性:{},值：{}",headMap.get(colIndex),content);
									        BeanUtils.setProperty(obj, headMap.get(colIndex),content);
			        				   }
								} catch (InvocationTargetException | IllegalAccessException e) {
									e.printStackTrace();
								}
			       // System.out.println("产生一个对象"+obj);
		        }
					 objs.add(obj);
				 }
	
	}
	

	/**
	 * 由实体类的注解的属性和get方法，和excel标题建立对应
	 * @param clz
	 * @return
	 */
	
	private List<ExcelHeader> getHeaderList(Class clz){
		List<ExcelHeader> headers = new ArrayList<ExcelHeader>();
		Method[] ms =clz.getDeclaredMethods();
		for (Method m :ms){
			String mn =m.getName();
			if (mn.startsWith("get")){
				if(m.isAnnotationPresent(ExcelResources.class)){
								ExcelResources er = m.getAnnotation(ExcelResources.class);
								mn = mn.substring(3).substring(0, 1).toLowerCase()+mn.substring(4);
								//System.out.print("类属性："+er.title()+ er.order()+ mn);
								headers.add(new ExcelHeader(er.title(), er.order(), mn));
					}
			  // System.out.println("-----------------------");
			}
		}
		return headers;
	}
	
	/**
	 * 根据第0行标题，和实体类建立对应，生成map表，对象的赋值方法
	 * @return
	 */
	private Map<Integer,String> getHeaderMap(String[] datas){
		Map<Integer,String> maps = new HashMap<Integer,String>();
		String title = "";
		//一行中的列号
		for(int colIndex =0 ; colIndex <  datas.length;colIndex++ ){
			//  System.out.println("第"+colIndex+"列，标题："+datas[colIndex]);
			//读取excel文档标题,无标题的列，产生null 报错
			  title = datas[colIndex] ==null ? Integer.toString(colIndex) : datas[colIndex];
			  //对标题昵称进行映射
			//todo:2.21注释掉，对过程为标题映射
			  //title = TitleStNaParse.getInstance().getName(title).trim();
			for(ExcelHeader eh : excelHeaders){
				if (eh.getTitle().trim().equals(title)){
					//第几列 属性
					maps.put(colIndex, eh.getMethodName());
					break;
				}
			}
		}
		return maps;
	}
	


}
